// @Author EthanScriptOn
// @Desc
package log_format

import (
	"errors"
	"fmt"
	"gitee.com/fatzeng/srf_switch_basic_components/initialization"
	"gitee.com/fatzeng/srf_switch_basic_components/util"
	"gitee.com/fatzeng/srf_switch_log/log"
	"gitee.com/fatzeng/srf_switch_log/log_define"
	"math"
	"runtime"
	"strings"
	"time"
)

type SrfSwitchTemplateParser func(logSnapshot *log.LogSnapshot) string

var templateParserStrategy = func() *initialization.OnceInitializer {
	initializer := initialization.GenerateOnceInitializer(log_define.SwitchLogPositionTag, log_define.TemplateParserStrategyInitTag)
	err := initializer.Set(math.MaxInt, func() (result interface{}, err error) {
		strategies := make(map[log_define.LogSnapshotOutBit]SrfSwitchTemplateParser)
		strategies[log_define.DATE] = func(logSnapshot *log.LogSnapshot) string {
			now := time.Now()
			format := "2006-01-02 15:04:05"
			noeFormatted := now.Format(format)
			return fmt.Sprintf("[[%v]] ", noeFormatted)
		}
		strategies[log_define.POSITION] = func(logSnapshot *log.LogSnapshot) string {
			_, file, line, ok := runtime.Caller(logSnapshot.CallDepth)
			if !ok {
				file = "unaware?"
				line = 0
			}
			return fmt.Sprintf("[%v][line: [%v]] ", file, line)
		}
		strategies[log_define.MESSAGE] = func(logSnapshot *log.LogSnapshot) string {
			template := "- [%v] "
			if logSnapshot.Key == nil {
				return fmt.Sprintf(template, "empty!")
			}
			outPut := strings.Builder{}
			outPut.WriteString("key: ")
			outPut.WriteString(util.Print(logSnapshot.Key))
			if len(logSnapshot.Value) != 0 {
				outPut.WriteString("value: ")
			}
			values := make(map[int]string)
			for index, val := range logSnapshot.Value {
				values[index] = util.Print(val)
			}
			outPut.WriteString(fmt.Sprintf("[%+v]", values))
			return fmt.Sprintf("- [%v] ", outPut.String())
		}
		strategies[log_define.LEVEL] = func(logSnapshot *log.LogSnapshot) string {
			return fmt.Sprintf("[%v]: ", logSnapshot.Level)
		}
		return strategies, nil
	})
	if err != nil {
		panic(err)
	}
	return initializer
}()

func GetTemplateParserStrategy() (map[log_define.LogSnapshotOutBit]SrfSwitchTemplateParser, error) {
	templateParserStrategyInstance, err := templateParserStrategy.Get()
	if err != nil {
		return nil, err
	}
	templateParserStrategyConversionInstance, ok := templateParserStrategyInstance.(map[log_define.LogSnapshotOutBit]SrfSwitchTemplateParser)
	if !ok {
		return nil, errors.New("templateParserStrategy type error need map[config_log_define.LogSnapshotBit]SrfSwitchTemplateParser")
	}
	return templateParserStrategyConversionInstance, nil
}
